﻿using ShengYueWorkShop.BLL.DataModel;
using ShengYueWorkShop.BLL.PublicHelper;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ShengYueWorkShop.BLL.Tcp
{
    public class ServerHelperOld
    {
        #region 变量
        private TcpClient _TcpClient { get; set; }
        private RichTextBox _RichBox { get; set; }
        private string _ClientName { get; set; }
        private string _Token { get; set; }
        /// <summary>
        /// 服务的根目录
        /// </summary>
        public string _ServerPath { get; set; }
        /// <summary>
        /// 当前工作目录
        /// </summary>
        private string _DirectoryPath { get; set; } = "\\";
        /// <summary>
        /// 数据流
        /// </summary>
        private NetworkStream _Stream;
        /// <summary>
        /// 接收的主数据包长度
        /// </summary>
       // private int _DataLenght = 0;
        #endregion
        /// <summary>
        /// 处理消息 object[2] 0=TcpClient,1=RichTextBox,2=Token,3=共享目录，
        /// </summary>
        /// <param name="fobject"></param>
        public void ProcClientMsg(object fobject)
        {
            try
            {
                object[] fobj = fobject as object[];
                _TcpClient = (TcpClient)fobj[0];
                _RichBox = (RichTextBox)fobj[1];
                _Token = (string)fobj[2];
                _ServerPath = (string)fobj[3];
                if (_TcpClient.Client.Connected)
                {
                    _ClientName = _TcpClient.Client.RemoteEndPoint.ToString();
                }
                LogWrite("接入");
                _Stream = _TcpClient.GetStream();
                //设置超时时间
                _Stream.ReadTimeout = TcpOperationCommand.TimeOut;
                _Stream.WriteTimeout = TcpOperationCommand.TimeOut;

                bool flag = true;
                while (flag)
                {
                    LogWrite("等待处理消息");
                    //读取消息并处理信息
                    flag = ReadMsgAndProc();
                }
            }
            catch (Exception ex)
            {
                LogWrite("操作错误:\r\n" + ex.ToString());
                if (_TcpClient.Client.Connected)
                {
                    //向客户端发送错误消息，让客户端关闭连接
                    WriteMsg(string.Format("{0}{1}", TcpOperationCommand.Error, ex.ToString()));
                }
            }
            finally
            {
                if (_TcpClient.Client.Connected)
                {
                    LogWrite("服务器主动退出");
                    WriteMsg(TcpOperationCommand.Closed);
                }
                _TcpClient?.Client.Close();
                _TcpClient?.Close();
            }
        }
        /// <summary>
        /// 消息处理机反馈
        /// </summary>
        private bool ReadMsgAndProc()
        {
            bool flag = false;
            string fMsg = ReadMsg();
            LogWrite("请求" + fMsg);
            if (fMsg.StartsWith(TcpOperationCommand.Closed))
            {
                LogWrite("退出");
                _TcpClient?.Client.Close();
                _TcpClient?.Close();
                return false;
            }
            else if (fMsg.StartsWith(TcpOperationCommand.Token))
            {
                fMsg = fMsg.Substring(TcpOperationCommand.Token.Length);
                flag = ValidateToken(fMsg);
                fMsg = string.Format("{0}{1}", TcpOperationCommand.Token, flag);

                LogWrite("处理" + fMsg);//日志
                WriteMsg(fMsg); //发送数据

                if (!flag) //Token验证失败，关闭连接
                {
                    _TcpClient?.Client.Close();
                    _TcpClient?.Close();
                }
            }
            else
            {
                if (fMsg.StartsWith(TcpOperationCommand.GetList))
                {
                    fMsg = GetList();
                }
                else if (fMsg.StartsWith(TcpOperationCommand.EnterDir))
                {
                    fMsg = fMsg.Substring(TcpOperationCommand.EnterDir.Length);
                    fMsg = EnterDirectory(fMsg);
                }
                else if (fMsg.StartsWith(TcpOperationCommand.ComeOutDir))
                {
                    fMsg = ComtOutDirectory();
                }
                else if (fMsg.StartsWith(TcpOperationCommand.GetPicZip))
                {
                    fMsg = fMsg.Substring(TcpOperationCommand.GetPicZip.Length);
                    fMsg = GetPicZip(fMsg);
                }
                LogWrite("处理" + fMsg);
                flag = WriteMsg(fMsg);
            }
            return flag;
        }
        #region 业务处理功能
        /// <summary>
        /// 验证Token
        /// </summary>
        /// <param name="pMsg"></param>
        /// <returns></returns>
        private bool ValidateToken(string pMsg)
        {
            bool flag = false;
            if (_Token.Length > 0)
            {
                if (_Token == pMsg)
                {
                    flag = true;
                }
            }
            return flag;
        }
        /// <summary>
        /// 获取当前目录下的文件及目录
        /// </summary>
        /// <returns></returns>
        private string GetList()
        {
            string fReturnStr = "";
            List<FileListStruct> fList = new List<FileListStruct>();
            FileListStruct fileInfo;
            if (_ServerPath.Length > 0)
            {
                string fPatch = _ServerPath;
                if (_DirectoryPath.Length > 0 && "/" != _DirectoryPath)
                {
                    fPatch += "/" + _DirectoryPath;
                }
                if (Directory.Exists(fPatch))
                {
                    //列出所有文件夹
                    DirectoryInfo directoryInfo = new DirectoryInfo(fPatch);
                    DirectoryInfo[] directories = directoryInfo.GetDirectories();
                    foreach (DirectoryInfo directory in directories)
                    {
                        fileInfo = new FileListStruct();
                        fileInfo.name = directory.Name;
                        fileInfo.IsDirectory = true;
                        fileInfo.Lenght = 0;
                        fList.Add(fileInfo);
                    }

                    // 列出所有文件
                    FileInfo[] files = new DirectoryInfo(fPatch).GetFiles();
                    foreach (FileInfo file in files)
                    {
                        fileInfo = new FileListStruct();
                        fileInfo.name = file.Name;
                        fileInfo.IsDirectory = false;
                        fileInfo.Lenght = (int)file.Length / 1024 / 1024;
                        fileInfo.CreateTime = file.CreationTime;
                        fList.Add(fileInfo);
                    }
                    fReturnStr = string.Format("{0}{1}"
                        , TcpOperationCommand.GetList
                        , JSONHelper.SerializeObject(fList));
                }
                else
                {
                    fReturnStr = string.Format("{0}{1}", TcpOperationCommand.Message, "目录不存在");
                }
            }
            else
            {
                fReturnStr = string.Format("{0}{1}", TcpOperationCommand.Message, "服务器没有设置可访问的根目录");
            }
            return fReturnStr;
        }
        /// <summary>
        /// 从当前目录进入下一级目录
        /// </summary>
        /// <param name="pDirectoryName"></param>
        /// <returns></returns>
        private string EnterDirectory(string pDirectoryName)
        {
            string fReturnStr = "";
            bool flag = false;
            if (pDirectoryName.Length > 0)
            {
                //服务器路径
                string fPatch = "";
                if ("\\" == _DirectoryPath)
                {
                    fPatch = "\\" + pDirectoryName;
                }
                else
                {
                    if (_DirectoryPath.EndsWith("\\"))
                    {
                        _DirectoryPath = _DirectoryPath.Substring(0, _DirectoryPath.Length - 2);
                    }
                    fPatch = _DirectoryPath + "\\" + pDirectoryName;
                }
                if (Directory.Exists(_ServerPath + fPatch))
                {
                    flag = true;
                    _DirectoryPath = fPatch;
                    fReturnStr = string.Format("{0}{1}", TcpOperationCommand.EnterDir, flag);
                }
            }
            if (!flag)
            {
                fReturnStr = string.Format("{0}{1}", TcpOperationCommand.Message, "目录不存在");
            }
            return fReturnStr;
        }
        /// <summary>
        /// 从当前目录返回到上级目录
        /// </summary>
        /// <returns></returns>
        private string ComtOutDirectory()
        {
            string fReturnStr = "";
            bool flag = false;
            if (_DirectoryPath.Length > 0 && "\\" != _DirectoryPath)
            {
                string[] strDir = _DirectoryPath.Split('\\');
                if (strDir.Length == 1)
                {
                    _DirectoryPath = "\\";
                }
                else
                {
                    _DirectoryPath = String.Join("\\", strDir, 0, strDir.Length - 2);
                }
                flag = true;
                fReturnStr = string.Format("{0}{1}", TcpOperationCommand.ComeOutDir, flag);
            }
            else
            {
                fReturnStr = string.Format("{0}{1}", TcpOperationCommand.Message, "已经是根目录");
            }
            return fReturnStr;
        }
        private string GetPicZip(string pFileName)
        {
            string fReturnStr = "";
            bool flag = false;
            if (pFileName.Length > 0)
            {
                if (pFileName.Contains(".jpg") || pFileName.Contains(".bmp"))
                {
                    if (_DirectoryPath.EndsWith("\\"))
                    {
                        _DirectoryPath = _DirectoryPath.Substring(0, _DirectoryPath.Length - 2);
                    }
                    //服务器路径
                    string fPatch = _ServerPath + "\\" + _DirectoryPath + "\\" + pFileName;
                    if (File.Exists(fPatch))
                    {
                        flag = true;
                        //压缩文件
                        LogWrite(string.Format("压缩图片:{0}", fPatch));
                        //根据要求变更图版大小
                        Bitmap fBitMap = new Bitmap(Image.FromFile(fPatch), new Size(600, 600));
                        fReturnStr = string.Format("{0}{1}"
                            , TcpOperationCommand.GetPicZip
                            , JSONHelper.SerializeObject(fBitMap));
                    }
                }
            }
            if (!flag)
            {
                fReturnStr = string.Format("{0}{1}", TcpOperationCommand.Message, "文件不存在");
            }
            return fReturnStr;
        }
        #endregion
        #region 消息发送及处理
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="pMsg"></param>
        private bool WriteMsg(string pMsg)
        {
            bool flag = false;
            ////数据转换
            //byte[] TcpDataBytes = Encoding.UTF8.GetBytes(pMsg);
            ////发送第一个数据，主数据包长度，同时判断连接是否正常
            //string fDataBuffer = string.Format("{0}{1}", TcpOperationCommand.DataLenght, TcpDataBytes.Length);
            //byte[] fDataByts = Encoding.UTF8.GetBytes(fDataBuffer);
            //_Stream.Write(fDataByts, 0, fDataByts.Length);
            ////处理数据 接受结果，判断客户端/服务端是否已经正确收到主数据包长度
            //if (ReadMsgAndProc() && _DataLenght == TcpDataBytes.Length)
            //{

            //}
            //else
            //{
            //    LogWrite("客户端接收的主数据包长度标识与服务器即将发送的长度不一致");
            //}
            return flag;
        }
        /// <summary>
        /// 接收消息
        /// </summary>
        /// <returns></returns>
        private string ReadMsg()
        {
            string fReturnStr = "";
            //分包数据集
            List<byte> packetBuffer = new List<byte>();
            //数据包长度
            int fDataLenght = 0;
            //已经接收的数据包长度
            int fReadDataLenght = 0;
            int fbytes;
            do
            {
                byte[] TcpDataBytes = new byte[TcpOperationCommand.BytesMaxLenght];
                fbytes = _Stream.Read(TcpDataBytes, 0, TcpDataBytes.Length);
                fReadDataLenght += fbytes;
                packetBuffer.AddRange(TcpDataBytes);
            }
            while (fReadDataLenght < fDataLenght);
            byte[] fullData = packetBuffer.ToArray();
            fReturnStr = Encoding.UTF8.GetString(fullData);
            return fReturnStr.TrimEnd('\0');
        }
        #endregion
        #region 打印操作日志
        private void LogWrite(string pLogStr)
        {
            if (_RichBox.Text.Length > 0)
            {
                _RichBox.Text += "\r\n";
            }
            if (_RichBox.Text.Length > 50000)
            {
                _RichBox.Text = "";
                _RichBox.Text += string.Format("{0} 清空日志\r\n", DateTime.Now);
            }
            _RichBox.Text += string.Format("{0} [{1}] {2}", DateTime.Now, _ClientName, pLogStr);
            _RichBox.ScrollToCaret();//光标定位在最后一行
        }
        #endregion







    }
}
